package com.eascs.web.api.view.method;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.eascs.common.util.ClassUtil;
import com.eascs.common.util.ObjectUtil;

public class ApiParamBuilder {

	public static List<ApiParam> buildApiParams(Type type) {
		Map<Type, ApiParam> context = new LinkedHashMap<>();
		ApiParamBuilder.buildApiParamMap(type, context);
		return new ArrayList<>(context.values());
	}

	public static void buildApiParamMap(Type type, Map<Type, ApiParam> context) {
		if (null == type)
			return;

		if (context.containsKey(type))
			return;

		if (context.size() > 0 && ClassUtil.isSimpaleType(type))
			return;

		ApiParam apiParam = new ApiParam(type);
		context.put(type, apiParam);

		if (ClassUtil.isSimpaleType(type))
			return;

		if (ClassUtil.isArray(type)) {
			ApiParamBuilder.buildApiParamMap(ClassUtil.getArrayType(type), context);
			return;
		}

		if (type instanceof ParameterizedType) {
			ApiParamBuilder.buildApiParamMap(ClassUtil.getActualType(type), context);
			return;
		}

		if (!(type instanceof Class))
			return;

		List<ApiOption> apiOptions = new ArrayList<>();
		Map<String, Field> fieldMap = ObjectUtil.buildXmlNameWithFieldMap((Class<?>) type);
		for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
			apiOptions.add(new ApiOption(entry.getKey(), entry.getValue()));
			Type subType = entry.getValue().getGenericType();
			if (ClassUtil.isSimpaleType(subType))
				continue;
			if (subType instanceof ParameterizedType)
				subType = ClassUtil.getActualType(subType);
			else if (ClassUtil.isArray(subType)) {
				subType = ClassUtil.getArrayType(subType);
			}
			ApiParamBuilder.buildApiParamMap(subType, context);
		}
		apiParam.setApiOptions(apiOptions);

	}
}
